package com.lvhr.rpc.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 响应
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RpcResponse implements Serializable {

    /**
     * 响应数据
     */
    private Object data;

    /**
     * 响应数据类型（预留）
     */
    private Class<?> dataType;

    /**
     * 响应信息
     */
    private String message;

    /**
     * 异常信息
     */
    private Exception exception;

    /**
     * 响应状态码（200表示成功，其他为错误码）
     */
    @Builder.Default
    private int code = 200;

    /**
     * 错误详情（用于传递额外信息）
     */
    private Map<String, Object> attachments;

    // ========== 静态工厂方法 ==========

    public static RpcResponse success(Object data) {
        return RpcResponse.builder()
                .data(data)
                .dataType(data != null ? data.getClass() : null)
                .code(200)
                .message("success")
                .build();
    }

    public static RpcResponse error(Exception e) {
        return RpcResponse.builder()
                .code(500)
                .message(e.getMessage())
                .exception(e)
                .build();
    }

    public static RpcResponse fail(String message) {
        return RpcResponse.builder()
                .code(400)
                .message(message)
                .build();
    }

    public static RpcResponse fail(int code, String message) {
        return RpcResponse.builder()
                .code(code)
                .message(message)
                .build();
    }

    // ========== 链式调用方法 ==========

    public RpcResponse addAttachment(String key, Object value) {
        if (this.attachments == null) {
            this.attachments = new HashMap<>();
        }
        this.attachments.put(key, value);
        return this;
    }

    public <T> T getAttachment(String key) {
        if (attachments == null) {
            return null;
        }
        return (T) attachments.get(key);
    }

    public RpcResponse withDataType(Class<?> dataType) {
        this.dataType = dataType;
        return this;
    }

    // ========== 状态判断方法 ==========

    public boolean isSuccess() {
        return code == 200;
    }

    public boolean hasException() {
        return exception != null;
    }

    public boolean hasAttachments() {
        return attachments != null && !attachments.isEmpty();
    }
}
